#pragma once
#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include "InetAddr.hpp"
#include "Socket.hpp"
#include "Log.hpp"
#include "Protocol.hpp"

using namespace log_ns;
using namespace socket_ns;

using process_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>)>;

class IOServer
{
public:
    IOServer(process_t process) : _process(process) {}

    ~IOServer() {}

    void Excute(SockSPtr sock, InetAddr &addr)
    {
        std::string packageStream;
        while (true)
        {
            // 1. 读取信息
            int n = sock->Recv(&packageStream);
            if (n == 0)
            {
                LOG(INFO, "client %s quit\n", addr.addrStr().c_str());
                break;
            }
            else if (n < 0)
            {
                LOG(ERROR, "read error: %s\n", addr.addrStr().c_str());
                break;
            }

            std::cout << "--------------------------------------------" << std::endl;
            std::cout << "packageStream: \n" << packageStream << std::endl;

            // 2. 报文提取
            std::string package = Decode(packageStream);
            if (package.empty())
                continue;

            // 3. 反序列化
            auto req = std::make_shared<Request>();
            std::cout << "package: \n" << package << std::endl;
            req->Deserialize(package);

            // 4. 业务处理
            auto resp = _process(req);

            // 5. 应答序列化
            std::string respJson;
            resp->Serialize(respJson);
            std::cout << "respjson: \n" << respJson << std::endl;

            // 6. 添加报头
            respJson = Encode(respJson);
             std::cout << "respjson add header done: \n" << respJson << std::endl;

            // 7. 发送
            sock->Send(respJson);
        }
    }

private:
    process_t _process;
};